#include "stdafx.h"
#include "qsplitter.h"
#include "qwindowpos.h"





#define DELTA			2
#define SP_BARWIDTH		5
#define SP_MAX			10000



using namespace micro::gui;



QSplitter::QSplitter()
{
    // Mouse is pressed down or not ?
    m_bIsPressed = false;
    m_fixed = false;
    
    // Min and Max range of the splitter.
    m_nMinFirst = 20;
    m_nMinSecond = 20 + SP_BARWIDTH;
    
    m_percent = 5000;
    m_sPos = -1;
    
    m_style = SPS_VERTICAL;
    m_bkColor = ::GetSysColor( COLOR_3DFACE );
    
    
    
    
    m_first = m_second = nullptr;
    
}
QSplitter::~QSplitter()
{

}
bool QSplitter::OnContextMenu( HWND h, QPoint& point )
{


    return false;
}



bool QSplitter::OnPreCreate( CREATESTRUCT& cs )
{
    QWindow::OnPreCreate( cs );
    cs.style =	WS_CLIPCHILDREN | WS_CHILD | WS_VISIBLE ;//|WS_CLIPSIBLINGS;// |WS_BORDER ;
    cs.lpCreateParams = this;/*pt a atasa clasa ferestrei}; */
    return true;
}

bool QSplitter::OnPreRegisterClass( WNDCLASS& wcex )
{
    QWindow::OnPreRegisterClass( wcex );
    
    
    wcex.style			=   CS_DBLCLKS   ;// | CS_HREDRAW | CS_VREDRAW   ; //ca sa se restearga
    
    wcex.hbrBackground	= ( HBRUSH )( COLOR_3DFACE + 1 ); //(HBRUSH)(COLOR_BTNFACE+1);
    wcex.lpszClassName = _T( "QSP" );
    
    LPWSTR cursor = IDC_SIZEWE;
    
    if ( m_style == SPS_VERTICAL )
    {
        //cursor = IDC_SIZEWE; //IDC_VSPC;
        //wcex.style			=   CS_VREDRAW;
    }
    else
    {
        cursor = IDC_SIZENS; //IDC_HSPC;
        //wcex.style			=     CS_HREDRAW;
    }
    
    wcex.hCursor = ::LoadCursor ( 0,  cursor  );
    return true;
    
}
UINT QSplitter::GetSplitterStyle()
{
    return m_style;
}
UINT QSplitter::GetSplitterPos()
{
    return m_sPos;
}


void QSplitter::SetBkColor( QCOLOR c )
{
    m_bkColor = c;
    Invalidate();
}


void QSplitter::SetSplitterStyle()
{
    m_style = ( m_style == SPS_VERTICAL ? SPS_HORIZONTAL : SPS_VERTICAL );
    
    LPWSTR cursor = IDC_SIZEWE;
    
    if ( m_style == SPS_VERTICAL )
    {
        //cursor = IDC_VSPC;		//IDC_SIZEWE;
    }
    else
    {
        cursor = IDC_SIZENS;		//IDC_HSPC;		//IDC_SIZENS;
    }
    
    HCURSOR h = ( HCURSOR ) SetClassLong( GCLP_HCURSOR, ( LONG_PTR ) ::LoadCursor ( 0,   cursor  )   );
    
    if ( h )
        ::DestroyCursor( h );
        
        
    UpdateLayout( true );
}



bool QSplitter::Create(  QWindow* pParent, int id, UINT style )
{

    m_style = style;
    
    QWindow::Create( pParent,  id , style ); //constructie indirecta
    
    // Create the two window panes
    if ( !m_first  || !m_second )
        throw QError( _T( "QSPC" ) );
        
    m_first->Create( this,  0 );
    m_second->Create( this, 1 );
    
    
    
    m_toolTip.Create( this );
    
    
    return true;
}


bool QSplitter::OnPaint( QGraphics* pdc )
{
    return true;
}

bool QSplitter::OnEraseBackground( QGraphics* pdc )
{
    QRect rc = GetClientRect();
    
    pdc->FillSolidRect( rc, m_bkColor );
    return true;
}


void QSplitter::SetPanels( QWindow* first, QWindow* second )
{

    m_first = first;
    m_second = second;
    
}


void  QSplitter::GetSplitterBarRect( QRect& rc ) const
{

    rc = m_rcSplitter;
    
    if ( m_style == SPS_VERTICAL )
    {
        rc.left = m_rcSplitter.left + m_sPos;
        //rc.top = m_rcSplitter.top;
        rc.right = rc.left  + SP_BARWIDTH;
        //rc.bottom = m_rcSplitter.bottom;
    }
    else
    {
        //rc.left = m_rcSplitter.left;
        rc.top = m_rcSplitter.top + m_sPos;
        //rc.right = m_rcSplitter.right;
        rc.bottom =  rc.top + SP_BARWIDTH;
    }
    
    
}


QString QSplitter::GetToolTip()
{

    TCHAR		sir[40];
    _stprintf_s( sir, 40, _T( "%.2f%%" ), m_percent / 100.0 );
    
    return QString ( sir );
}

bool QSplitter::OnMouseMove( UINT nFlags, QPoint& pt )
{

    if ( !m_bIsPressed )
        return true;
        
     if( m_ptDown.Distance(pt) < DELTA)
		return true;
        
    QRect rc = GetClientRect();
    
    if ( m_style == SPS_VERTICAL )
    {
        if ( pt.x <= m_nMinFirst )
            pt.x = 0;
        else
            if ( pt.x >= rc.right - m_nMinSecond )
                pt.x =  rc.right - SP_BARWIDTH;
                
    }
    else
    {
        if ( pt.y <= m_nMinFirst )
            pt.y = 0;
        else
            if ( pt.y >= rc.bottom - m_nMinSecond )
                pt.y =  rc.bottom - SP_BARWIDTH;
    }
    
    
    
    
    int newPos = 0;
    
    if ( m_style == SPS_VERTICAL )
        newPos = pt.x; //- m_rcSplitter.left - m_cxyDragOffset;
    else
        newPos = pt.y;// - m_rcSplitter.top - m_cxyDragOffset;
        
        
        
        
    if ( m_sPos != newPos )
    {
        if ( SetSplitterPos( newPos, true ) ) //asta face invalidate
            UpdateWindow();
            
            
            
        m_toolTip.UpdateTipText( GetToolTip(), GetHandle() );
        m_toolTip.TrackPosition( pt.x, pt.y );
        
    }
    
    return true;
}



bool QSplitter::OnLButtonDown( UINT nFlags, QPoint& point )
{

    m_bIsPressed = true;
    SetCapture();
    
    
    m_ptDown = point;
    
    
    ///tooltip
    m_toolTip.AddTool( GetHandle(), GetToolTip() );
    
    
    m_toolTip.TrackActivate(  TRUE,  GetHandle() );
    m_toolTip.Popup();
    
    
    return true;
    
}

bool QSplitter::OnLButtonUp( UINT nFlags, QPoint& point )
{
    m_bIsPressed = false;
    ReleaseCapture();
    
    
    m_toolTip.Pop();
    m_toolTip.DelTool( GetHandle() );
    
    return true;
}



void  QSplitter::SetMinSizes( int first, int second )
{
    m_nMinFirst  = first;
    m_nMinSecond = second;
}






void QSplitter::UpdatePosFromPercent()
{
    int cxyTotal = m_style == SPS_VERTICAL ? ( m_rcSplitter.right - m_rcSplitter.left - SP_BARWIDTH ) : ( m_rcSplitter.bottom - m_rcSplitter.top - SP_BARWIDTH );
    
    if ( cxyTotal > 0 )
    {
        //int newPos
        m_sPos = ::MulDiv( m_percent, cxyTotal, SP_MAX );
        //SetSplitterPos(newPos, false);
    }
}
void QSplitter::UpdatePercentFromPos()
{
    int cxyTotal = m_style == SPS_VERTICAL ? ( m_rcSplitter.right - m_rcSplitter.left - SP_BARWIDTH ) : ( m_rcSplitter.bottom - m_rcSplitter.top - SP_BARWIDTH );
    
    if ( cxyTotal > 0 )
        m_percent = ::MulDiv( m_sPos, SP_MAX, cxyTotal );
    else
        m_percent = 0;
}


bool QSplitter::OnLButtonDblClk( UINT nFlags, QPoint& point )
{
    SetSplitterPos();//juma juma
    return true;
}
bool QSplitter::SetSplitterPercent( UINT percent, bool bUpdate )
{
    m_percent = percent;
    
    //if(IsProportional())
    UpdatePosFromPercent();
    
    if ( bUpdate )
    {
        UpdateLayout();
    }
    
    return true;
}

bool  QSplitter::SetSplitterPos( int xyPos, bool bUpdate )
{
    if ( xyPos == -1 ) // -1 == middle
    {
        if ( m_style == SPS_VERTICAL )
            xyPos = ( m_rcSplitter.Width() - SP_BARWIDTH ) / 2;
        else
            xyPos = ( m_rcSplitter.Height() - SP_BARWIDTH ) / 2;
    }
    
    // Adjust if out of valid range
    int cxyMax = 0;
    
    if ( m_style == SPS_VERTICAL )
        cxyMax = m_rcSplitter.right - m_rcSplitter.left;
    else
        cxyMax = m_rcSplitter.bottom - m_rcSplitter.top;
        
    if ( xyPos < 0 )
        xyPos = 0;
    else
        if ( xyPos > cxyMax )
            xyPos = cxyMax;
            
    // Set new position and update if requested
    bool bRet = ( m_sPos != xyPos );
    m_sPos = xyPos;
    
    
    if ( IsProportional() )
        UpdatePercentFromPos();
        
        
    if ( bUpdate && bRet )
    {
        UpdateLayout(true);
    }
    
    return bRet;
}




bool QSplitter::OnSize( int type, int cx, int cy )
{

    UpdateLayout( true );
    return true;
}
void QSplitter::UpdateLayout( bool redraw )
{
    m_rcSplitter = GetClientRect();
    
    if ( IsProportional() )
        UpdatePosFromPercent();
        
        
        
    QRect rc1, rc2;
    rc1 = rc2 = m_rcSplitter;
    
    
    if ( m_style == SPS_VERTICAL )
    {
        rc1.right = m_rcSplitter.left + m_sPos;
        rc2.left = m_rcSplitter.left + m_sPos + SP_BARWIDTH ;
    }
    else
    {
        rc1.bottom = m_rcSplitter.top + m_sPos;
        rc2.top = m_rcSplitter.top + m_sPos + SP_BARWIDTH ;
    }
    
    QWindowPos pos( 2 );
    pos.MoveWindow( m_first->GetHandle(), rc1, redraw );
    pos.MoveWindow( m_second->GetHandle(), rc2, redraw );
    
    
    QRect rc;
    GetSplitterBarRect( rc );
    InvalidateRect( rc );
    
    
}
